package rabid;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Date;
import java.util.HashMap;

import control.Constants;

public class Index {
	
	//total word count of corpus
	private String wordCount;
	
	//total char count of corpus
	private String charCount;
	
	//this array contains the names of the corpus files in the same order
	//in which the wordcounts are stored in the index hashmap.
	private String[] corpusFiles;
	
	private String creationDate;
	
	private String breakChars;
	
	private String stopWordsFile;
	
	private String directory;
	
	private long fileSize;
	
	private HashMap  hashMap;
	
	private ObjectInputStream objectStream;
	
	public Index() throws IOException, FileNotFoundException {

		FileInputStream fileStream = new FileInputStream(Constants.INDEX_FILE);
		objectStream = new ObjectInputStream(fileStream); 
		initIndex();
		objectStream.close();
		fileStream.close();
	}//end constructor
	
	private void initIndex() {
		
		//setCreationDate();
		creationDate = readIndexDataString();
		breakChars = readIndexDataString(); 
		stopWordsFile = readIndexDataString();
		charCount = readIndexDataString();
		wordCount = readIndexDataString();

		setCorpusFiles();
		
		try {
			hashMap = (HashMap)objectStream.readObject();
		} catch (Exception e) {
			//TODO: Exception handling
		}
		
		directory = System.getProperty("user.dir");
		File file = new File(Constants.INDEX_FILE);
		fileSize = file.length();
	}//end initIndex(...)

	/**
	 * This function reads a set of characters up to where two ==
	 * are found. Then the characters are returned as a string
	 * @return the string that was read from the index files
	 */
	private String readIndexDataString() {
		
		StringBuffer dataString = new StringBuffer();
		int delCount = 0;
		char thisChar;
		
		try {
			while(true) {
				thisChar = objectStream.readChar();
				
				if(thisChar == '=') {
					delCount++;
					if(delCount > 1) {
						break;
					}
					continue;
				}
				//last char was a '=' and this one isnt so no delimeter
				if(delCount > 0) {
					dataString.append('=');
					delCount = 0;
				}
				dataString.append(thisChar); 
			}
		} catch (IOException e) {
			//TODO: Inform controller
		}
		return dataString.toString();
	}//end readIndexDataString

	/**
	 * Save the name of the corpus files in an array that matches
	 * the hashMap array 
	 */
	private void setCorpusFiles() {
		
		String files = readIndexDataString();
		Integer fileCt = new Integer(files); 
		corpusFiles = new String[fileCt.intValue()];
		
		for (int i = 0; i < corpusFiles.length; i++) {
			corpusFiles[i] = readIndexDataString();
		}
	}//end setCorpusFiles

	/**
	 * Gets the complete path of a file given the file name
	 * @param filename the file for which the path is needed
	 * @return the string with the absolute path to the file or
	 * null if not found.
	 */
	public String getFilePath(String filename) {
		
		if(filename != null) {
			for (int i = 0; i < corpusFiles.length; i++) {
				if(corpusFiles[i].endsWith(filename)) {
					return corpusFiles[i];
				}
			}
		}
		return null;
	}//end getFilePath
	
	public int getFileIndex(String filename) {
		
		if(filename != null) {
			for (int i = 0; i < corpusFiles.length; i++) {
				if(corpusFiles[i].endsWith(filename)) {
					return i;
				}
			}
		}
		return -1;
	}//end getFilePath
	
	/**
	 * Reads the delimeters that separate the information in the index
	 * file. e.g. == and ##
	 */
	private void readDelimeters() {
		try {
			objectStream.readChar();
			objectStream.readChar();
		} catch (IOException e) {
			//TODO: Inform controller
		}
	}
	
	//getter for the hashmap
	public HashMap getHashMap() {
		return hashMap;
	}
	
	//getter for the size of the corpus
	public int getCorpusSize() {
		return corpusFiles.length;
	}
	
	//getter for the files
	public String[] getCorpusFiles() {
		return corpusFiles;
	}
	
	public int getWordCount() {
		Integer wc = new Integer(wordCount);
		return wc.intValue();
	}
	
	public int getCharCount() {
		Integer cc = new Integer(charCount);
		return cc.intValue();
	}
	
	public String getDate() {
		return creationDate;
	}
	
	public String getBreakChars() {
		return breakChars;
	}
	
	public String getStopWordFile() {
		return stopWordsFile;
	}
	/**
	 * Function to get file, word and char counts
	 * @return the string with the info
	 */
	public String getStats() {
		String stats = "--- Stats ---" + '\n';
		stats = stats.concat("File Count: " + corpusFiles.length + '\n');
		stats = stats.concat("Word Count: " + wordCount + '\n');
		stats = stats.concat("Character Count: " + charCount);
		
		return stats;
	}//end getStats
	
	/**
	 * 
	 * @return
	 */
	public String getIndexInfo() {
		String indexInfo =  "--- Index Info ---" + '\n';
		indexInfo = indexInfo.concat("Name: " + Constants.INDEX_FILE + '\n');
		indexInfo = indexInfo.concat("Created on " + creationDate + '\n');
		indexInfo = indexInfo.concat("Stop words file: " + stopWordsFile + '\n');
		indexInfo = indexInfo.concat("Break characters: " + breakChars + '\n');
		indexInfo = indexInfo.concat("Directory: " + directory + '\n');
		indexInfo = indexInfo.concat("Size: " + fileSize + " bytes");
		
		//size
		//directory
		return indexInfo;
	}//getIndexInfo
	
	public static void main (String args[]) {
		
		Index index = null;
		try {
			 index = new Index();
		} catch (Exception e) {
			System.out.println("An exception: " + e);
		}
		System.out.println(index.getStats());	
		System.out.println(index.getIndexInfo());
	}
} //end Index
